package sky.demo.maven;

import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.apache.maven.settings.Mirror;
import org.apache.maven.settings.Proxy;
import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.building.DefaultSettingsBuilderFactory;
import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
import org.apache.maven.settings.building.SettingsBuilder;
import org.apache.maven.settings.building.SettingsBuildingException;
import org.apache.maven.wagon.Wagon;
import org.codehaus.plexus.DefaultPlexusContainer;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.PlexusContainerException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.eclipse.aether.AbstractRepositoryListener;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.impl.DefaultServiceLocator;
import org.eclipse.aether.impl.RemoteRepositoryManager;
import org.eclipse.aether.internal.transport.wagon.PlexusWagonProvider;
import org.eclipse.aether.repository.Authentication;
import org.eclipse.aether.repository.AuthenticationSelector;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.MirrorSelector;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
import org.eclipse.aether.resolution.ArtifactDescriptorResult;
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
import org.eclipse.aether.transport.wagon.WagonProvider;
import org.eclipse.aether.transport.wagon.WagonTransporterFactory;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.eclipse.aether.util.repository.DefaultMirrorSelector;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

public class ResolverInitializer {

    public static void main(String[] args) throws Exception {
        // 创建默认的系统和服务定位器
        DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
        RepositorySystem system = newRepositorySystem(locator);
        // 加载 settings.xml 文件
        Settings settings = loadSettings("C:\\devtools\\apache-maven-3.9.9\\conf\\settings.xml");

        // 创建带有 settings 的 session
        RepositorySystemSession session = newSession(system, settings);
        // 指定本地POM文件的位置
        File pomFile = new File("pom.xml");

        // 确保POM文件存在
        if (!pomFile.exists()) {
            throw new FileNotFoundException("POM file not found at: " + pomFile.getAbsolutePath());
        }

        System.out.println("Reading POM file from: " + pomFile.getAbsolutePath());

        // 使用MavenXpp3Reader解析pom.xml文件
        Model model = readPom(pomFile);
        String groupId = model.getGroupId();
        String artifactId = model.getArtifactId();
        String version = model.getVersion();
        // 打印POM文件中的依赖信息，用于调试
        if (model.getDependencies() != null && !model.getDependencies().isEmpty()) {
            System.out.println("Dependencies in POM:");
            for (org.apache.maven.model.Dependency dependency : model.getDependencies()) {
                System.out.println(dependency.getGroupId() + ":" + dependency.getArtifactId() + ":" + dependency.getVersion());
            }
        } else {
            System.out.println("No dependencies found in POM.");
        }

        // 使用从POM文件中读取的坐标创建Artifact对象
        String artifactStr = groupId + ":" + artifactId + ":" + version;
        artifactStr = "org.apache.maven:maven-aether-provider:3.3.9";
        System.out.println("Using artifact coordinates: " + artifactStr);
        Artifact artifact = new DefaultArtifact(artifactStr);

        // 创建请求以解析POM
        ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest(artifact, Collections.emptyList(), null);
        descriptorRequest.addRepository(getRemoteRepository());
        try {
            ArtifactDescriptorResult descriptorResult = system.readArtifactDescriptor(session, descriptorRequest);
            if (descriptorResult.getDependencies() == null || descriptorResult.getDependencies().isEmpty()) {
                System.out.println("No dependencies found in resolved artifact.");
            } else {
                // 获取并打印所有依赖
                for (Dependency dependency : descriptorResult.getDependencies()) {
                    System.out.println("Resolved Dependency: " + dependency.getArtifact().getGroupId() + ":" + dependency.getArtifact().getArtifactId() + ":" + dependency.getArtifact().getVersion());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Failed to resolve artifact: " + e.getMessage());
        }

    }
    // 在 newSession 方法中添加 RemoteRepositoryManager 到 session
    private static RepositorySystemSession newSession(RepositorySystem system, Settings settings) {
        DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();

        LocalRepository localRepo = new LocalRepository("target/local-repo");
        session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));

        // 设置 RemoteRepositoryManager 到 session
//        RemoteRepositoryManager remoteRepositoryManager = system.newRepositoryLayoutFactory().getRepositoryLayout("default").getRemoteRepositoryManager();
//        session.setConfigProperty("remoteRepositoryManager", remoteRepositoryManager);
        // 获取 RemoteRepositoryManager 并设置到 session
//        RemoteRepositoryManager remoteRepositoryManager = system.newRepositoryManager(session);
//        session.setConfigProperty("remoteRepositoryManager", remoteRepositoryManager);

        session.setRepositoryListener(new AbstractRepositoryListener() {});

        // 添加中央仓库
        List<RemoteRepository> repos = new ArrayList<>();
        RemoteRepository central = getRemoteRepository();
        repos.add(central);

        // 应用 settings 中的配置
        applySettingsToSession(session, settings);

        return session;
    }

    private static RemoteRepository getRemoteRepository() {
        RemoteRepository central = new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2").build();
        return central;
    }

    private static RepositorySystem newRepositorySystem(DefaultServiceLocator locator) throws PlexusContainerException, ComponentLookupException {
        // 初始化 Plexus 容器
        PlexusContainer container = new DefaultPlexusContainer();
        locator.addService(RepositoryConnectorFactory.class, org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory.class);
        locator.setServices(WagonProvider.class, new PlexusWagonProvider(container));
        locator.addService(TransporterFactory.class, WagonTransporterFactory.class);
        return locator.getService(RepositorySystem.class);
    }

    private static void applySettingsToSession(DefaultRepositorySystemSession session, Settings settings) {
        // 创建 MirrorSelector 并应用到 session
        MirrorSelector mirrorSelector = createMirrorSelector(settings);
        session.setMirrorSelector(mirrorSelector);

        // 创建 AuthenticationSelector 并应用到 session
//        AuthenticationSelector authenticationSelector = createAuthenticationSelector(settings);
//        session.setAuthenticationSelector(authenticationSelector);
    }

    private static MirrorSelector createMirrorSelector(Settings settings) {
        DefaultMirrorSelector mirrorSelector = new DefaultMirrorSelector();
        for (Mirror mirror : settings.getMirrors()) {
            mirrorSelector.add(mirror.getId(), mirror.getUrl(), mirror.getLayout(), true, mirror.getMirrorOf(),null);
        }
        return mirrorSelector;
    }

    private static Settings loadSettings(String settingsPath) throws IOException, SettingsBuildingException {
        SettingsBuilder settingsBuilder = new DefaultSettingsBuilderFactory().newInstance();
        DefaultSettingsBuildingRequest request = new DefaultSettingsBuildingRequest();
        request.setGlobalSettingsFile(new File(settingsPath));
        return settingsBuilder.build(request).getEffectiveSettings();
    }
    private static Model readPom(File pomFile) throws IOException, XmlPullParserException {
        MavenXpp3Reader reader = new MavenXpp3Reader();
        try (FileReader fileReader = new FileReader(pomFile)) {
            return reader.read(fileReader);
        }
    }

    public static RepositorySystemSession newMavenRepositorySystemSession(RepositorySystem system) {
        DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();

        LocalRepository localRepo = new LocalRepository("target/local-repo");
        session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));

        session.setTransferListener(new ConsoleTransferListener());
        session.setRepositoryListener(new ConsoleRepositoryListener());

        return session;
    }


}
